package com.rdc.example.service.impl;

import com.rdc.example.bean.PageBean;
import com.rdc.example.bean.Result;
import com.rdc.example.bean.dto.PlayListDTO;
import com.rdc.example.bean.dto.SongDTO;
import com.rdc.example.dao.impl.*;
import com.rdc.example.entity.News;
import com.rdc.example.entity.Song;
import com.rdc.example.entity.User;
import com.rdc.example.util.FileUtil;
import org.apache.commons.fileupload.FileItem;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static com.rdc.example.util.FileUtil.uploadFile;

public class SongServiceImpl implements com.rdc.example.service.SongService {
//    public static void main(String[] args) throws Exception {
//        SongServiceImpl songService = new SongServiceImpl();
////        PageBean<SongDTO> page=songService.listSongIdListOutPlayListId(5,1,10);
////        System.out.println("s1 "+page.getRows());
////        System.out.println("s2 "+page.getTotalCount());
// //       System.out.println(songService.startReview(1,2));
//  //      System.out.println(songService.startReview(7,2));
////        Integer[] id = {1,2,3,4,5,6,7,8,9};
////        for(int i=0;i<50;i++){
////        SongDTO s=(SongDTO)(songService.getRandomSong().getData());
////
////        }
//    }

    SongDaoImpl songDao=new SongDaoImpl();
    UserDaoImpl userDao = new UserDaoImpl();
    SongLikesDaoImpl songLikesDao=new SongLikesDaoImpl();
    PlayListSongDaoImpl playListSongDao=new PlayListSongDaoImpl();
    NewsDaoImpl newsDao=new NewsDaoImpl();
    FollowDaoImpl followDao=new FollowDaoImpl();

    @Override
    public Result insertSong(SongDTO songDTO) throws Exception {
        Song song=convertToEntity(songDTO);
        boolean insert = songDao.insert(song);
        return insert ? Result.success("添加成功", null)
                : Result.fail("添加失败", null);
    }

    @Override
    public Result insertSong(SongDTO songDTO, List<FileItem> fileItems) throws Exception {
        Song song=convertToEntity(songDTO);
        Result fileResult=uploadFile(fileItems,1);
        if(fileResult.getCode()==200){
            //如果上传成功，就存入song
            song.setSongPath((String) fileResult.getData());
        }else{
            //上传失败，直接返回fileResult
            return fileResult;
        }
        boolean insert = songDao.insert(song);
        return insert?Result.success("添加成功",null)
            : Result.fail("添加失败", null);
    }

    @Override
    public Result deleteSongById(Integer songId,Integer userId) throws Exception {
        //获取用户
        User user=userDao.getUserById(userId);
        //获取歌曲
        Song song=songDao.getSongById(songId);
        //权限检测 是不是自己的，是不是管理员
        if(!user.getId().equals(song.getUserId())&&user.getUserType()!=3){
            return Result.fail("权限不足", null);
        }

        boolean delete = songDao.deleteSongById(songId);
        if (!delete) {
            return Result.fail("删除失败", null);
        }
        //删除对应文件
        boolean deleteFile= FileUtil.deleteFile(song.getSongPath());
        return deleteFile ? Result.success("删除成功", null)
                : Result.fail("歌曲信息删除成功，文件删除失败", null);
    }

    @Override
    public Result updateSong(SongDTO songDTO) throws Exception {
        Song song=convertToEntity(songDTO);
        boolean update = songDao.updateSong(song);
        return update ? Result.success("更新成功", null)
                : Result.fail("更新失败", null);
    }

    @Override
    public Result updateSong(SongDTO songDTO, List<FileItem> fileItems) throws Exception {
        Song song=convertToEntity(songDTO);
        Result fileResult=uploadFile(fileItems,1);
        if(fileResult.getCode()==200){
            //如果上传成功，就存入song
            song.setSongPath((String) fileResult.getData());
        }else{
            //上传失败，直接返回fileResult
            return fileResult;
        }
        boolean insert = songDao.updateSong(song);
        return insert ? Result.success("添加成功", null)
                : Result.fail("添加失败", null);
    }



    @Override
    public Result getSongById(Integer id) throws Exception {
        Song song = songDao.getSongById(id);
        //看看是不是空，决定返回结果
        return (song!=null) ? Result.success("获取成功", convertToDto(song))
                : Result.fail("获取失败，结果为空", null);
    }

    @Override
    public Result getRandomSong() throws Exception {
        Song song = songDao.getRandomSong();
        //单独补充用户名称
        if (song==null) {
            return  Result.success("获取失败，没有歌曲可展示",null);
        }
        User user=userDao.getUserById(song.getUserId());
        SongDTO songDTO=convertToDto(song);
        songDTO.setUserName(user.getUserName());
        return  Result.success("获取成功",songDTO);
    }


    @Override
    public Result getSongListByUserId(Integer userId) throws Exception {
        List<Song> songList=songDao.listSongByUserId(userId);
        //看看是不是空，决定返回结果
        return (songList!=null) ? Result.success("获取成功", convertAndEnrichSongs(songList))
                : Result.fail("获取失败，结果为空", null);
    }

    @Override
    public PageBean<SongDTO> getSongListByUserId(Integer userId, Integer currentPage, Integer pageSize) throws Exception {
        Integer pageBegin=(currentPage-1)*pageSize;
        //调用dao获取数据
        List<Song> songList=songDao.getSongListByPageAndUserId(userId, pageBegin, pageSize);
        Integer totalCount=songDao.countSongByUserId(userId);
        //封装PageBean
        PageBean<SongDTO> pageBean=new PageBean<>();
        pageBean.setTotalCount(totalCount);
        pageBean.setRows(convertAndEnrichSongs(songList));
        return pageBean;
    }

    @Override
    public PageBean<SongDTO> getLikeSongListByUserId(Integer userId, Integer currentPage, Integer pageSize) throws Exception {
        Integer pageBegin=(currentPage-1)*pageSize;
        //调用dao获取songIds
        List<Integer> songIds = songLikesDao.getSongIdListByUserId(userId);
        List<Song>songList= songDao.getSongListByIdList(songIds, pageBegin, pageSize);
        //总数等于ids的数量
        Integer totalCount=songIds.size();
        //封装PageBean
        PageBean<SongDTO> pageBean=new PageBean<>();
        pageBean.setTotalCount(totalCount);
        pageBean.setRows(convertAndEnrichSongs(songList));
        return pageBean;
    }

    @Override
    public PageBean<SongDTO> getSongListByPageAndColumnId(Integer columnId, Integer currentPage, Integer pageSize) throws Exception {
        Integer pageBegin=(currentPage-1)*pageSize;
        //调用dao
        List<Song>songList= songDao.getSongListByPageAndColumnId(columnId, pageBegin, pageSize);
        Integer totalCount=songDao.countSongByColumnId(columnId);
        //封装PageBean
        PageBean<SongDTO> pageBean=new PageBean<>();
        pageBean.setTotalCount(totalCount);
        pageBean.setRows(convertAndEnrichSongs(songList));
        return pageBean;
    }

    @Override
    public PageBean<SongDTO> getSongListByPageAndColumnIdWithNull(Integer columnId, Integer userId, Integer currentPage, Integer pageSize) throws Exception {
        Integer pageBegin=(currentPage-1)*pageSize;
        //调用dao
        List<Song> songList= songDao.getSongListByPageAndColumnIdWithNull(columnId,userId,pageBegin,pageSize);
        Integer totalCount=songDao.countSongByColumnIdWithNull(columnId,userId);
        //封装PageBean
        PageBean<SongDTO> pageBean=new PageBean<>();
        pageBean.setTotalCount(totalCount);
        pageBean.setRows(convertAndEnrichSongs(songList));
        return pageBean;
    }

    @Override
    public PageBean<SongDTO> getSongListByPlayListId(Integer playListId, Integer currentPage, Integer pageSize) throws Exception {
        Integer pageBegin=(currentPage-1)*pageSize;
        //调用dao获取songIds
        List<Integer> songIds = playListSongDao.listSongIdListByPlayListId(playListId);
        List<Song>songList= songDao.getSongListByIdList(songIds, pageBegin, pageSize);
        //总数等于ids的数量
        Integer totalCount=songIds.size();
        //封装PageBean
        PageBean<SongDTO> pageBean=new PageBean<>();
        pageBean.setTotalCount(totalCount);
        pageBean.setRows(convertAndEnrichSongs(songList));
        return pageBean;
    }

    @Override
    public PageBean<SongDTO> listSongIdListOutPlayListId(Integer playListId, Integer currentPage, Integer pageSize) throws Exception {
        Integer pageBegin=(currentPage-1)*pageSize;
        //所有songIds
        List<Integer> allSongIds = songDao.getSongIdList();
        //System.out.println("all:"+allSongIds);
        //对应playList列表中songIds
        List<Integer> playListSongIds = playListSongDao.listSongIdListByPlayListId(playListId);
        //System.out.println("small"+playListSongIds);
        // 获取不在playList列表中的歌曲ids
        List<Integer> getSongIds = new ArrayList<>();
        for (Integer songId : allSongIds) {
            if (!playListSongIds.contains(songId)) {
                getSongIds.add(songId);
            }
        }
        List<Song>songList= songDao.getSongListByIdList(getSongIds, pageBegin, pageSize);
        //总数等于ids的数量
        Integer totalCount=getSongIds.size();
        //封装PageBean
        PageBean<SongDTO> pageBean=new PageBean<>();
        pageBean.setTotalCount(totalCount);
        pageBean.setRows(convertAndEnrichSongs(songList));
        return pageBean;
    }

    @Override
    public PageBean<SongDTO> searchSongsByTitleAndLikeDesc(String keyword, Integer currentPage, Integer pageSize) throws Exception {
        Integer pageBegin=(currentPage-1)*pageSize;
        //调用dao
        List<Song>songList= songDao.searchSongsByTitleAndLikeDesc(keyword, pageBegin, pageSize);
        Integer totalCount=songDao.countSearchSongsByTitle(keyword);
        //封装PageBean
        PageBean<SongDTO> pageBean=new PageBean<>();
        pageBean.setTotalCount(totalCount);
        pageBean.setRows(convertAndEnrichSongs(songList));
        return pageBean;
    }

    @Override
    public PageBean<SongDTO> searchSongsByTitleAndCreatAtDesc(String keyword, Integer currentPage, Integer pageSize) throws Exception {
        Integer pageBegin=(currentPage-1)*pageSize;
        //调用dao
        List<Song>songList= songDao.searchSongsByTitleAndCreatAtDesc(keyword, pageBegin, pageSize);
        Integer totalCount=songDao.countSearchSongsByTitle(keyword);
        //封装PageBean
        PageBean<SongDTO> pageBean=new PageBean<>();
        pageBean.setTotalCount(totalCount);
        pageBean.setRows(convertAndEnrichSongs(songList));
        return pageBean;
    }

    @Override
    public PageBean<SongDTO> searchSongsByTitleAndLikeOrCreatAtDesc(String keyword, Integer currentPage, Integer pageSize, Integer type) throws Exception {
        Integer pageBegin=(currentPage-1)*pageSize;
        //调用dao  0->按点赞的排序   1->按创建时间的排序
        //System.out.println("in "+keyword+" "+currentPage+" "+pageSize);
        List<Song>songList= (type == 0)? songDao.searchSongsByTitleAndLikeDesc(keyword, pageBegin, pageSize)
                :songDao.searchSongsByTitleAndCreatAtDesc(keyword, pageBegin, pageSize);
        //两排序的totalCount是一样的
        Integer totalCount=songDao.countSearchSongsByTitle(keyword);
        //封装PageBean
        PageBean<SongDTO> pageBean=new PageBean<>();
        pageBean.setTotalCount(totalCount);
        pageBean.setRows(convertAndEnrichSongs(songList));
        //System.out.println("out"+totalCount+" "+pageBean.getRows());
        return pageBean;
    }

    @Override
    public PageBean<SongDTO> getSongListForCheck(Integer userId, Integer currentPage, Integer pageSize) throws Exception {
        Integer pageBegin=(currentPage-1)*pageSize;
        //调用dao
        //System.out.println("in "+keyword+" "+currentPage+" "+pageSize);
        List<Song>songList= songDao.getSongListForReview(userId,pageBegin,pageSize);
        Integer totalCount=songDao.countSongListForReview(userId);
        //封装PageBean
        PageBean<SongDTO> pageBean=new PageBean<>();
        pageBean.setTotalCount(totalCount);
        pageBean.setRows(convertAndEnrichSongs(songList));
        //System.out.println("out"+totalCount+" "+pageBean.getRows());
        return pageBean;
    }

    @Override
    public Result startReview(Integer userId, Integer songId) throws Exception {
        if (userId==null || songId==null) {
            return Result.fail("userId或songId不为空",null);
        }
        //1,是不是自己审核的
        Song song=songDao.getSongById(songId);
        if(song.getCheckId().equals(userId)) {
            return Result.success("开始审核成功",null);
        }
        //2是不是未审核状态
        boolean start = songDao.startReview(songId,userId);
       /* return start? Result.success("开始审核成功",null)
                :Result.fail("开始审核失败，该歌曲已被其他管理员审核",null);*/
        if(!start) {
            //高并发情况
            return Result.fail("开始审核失败，该歌曲已被其他管理员审核",null);
        }
        //操作成功，通知作者
        Integer receiverId=song.getUserId();
        News news=new News();
        news.setReceiverId(receiverId);
        news.setContent("您的歌曲"+song.getName()+"正在审核中！");
        boolean sendAuthor = newsDao.insert(news);
        return sendAuthor ? Result.success("操作成功",null)
                :Result.fail("操作成功,发送消息失败",null);
    }

    @Override
    public Result passReview(Integer songId) throws Exception {
        if (songId==null) {
            return Result.fail("songId不为空",null);
        }
        boolean pass = songDao.passReview(songId);
        if (!pass) {
            return Result.fail("操作失败",null);
        }
        //操作成功，通知作者
        Song song=songDao.getSongById(songId);
        Integer receiverId=song.getUserId();
        News news=new News();
        news.setReceiverId(receiverId);
        news.setContent("您的歌曲"+song.getName()+"审核通过！");
        boolean sendAuthor = newsDao.insert(news);

        //通知关注者
        User user=userDao.getUserById(song.getUserId());
        //获取关注者ids
        List<Integer> followedIds=followDao.listUserIdByFollowedId(song.getUserId());
        String msg="我("+user.getUserName()+")的新歌< "+song.getName()+" >已上线，快来听吧";
        boolean sendFans= newsDao.batchInsertMessages(song.getUserId(),msg,followedIds);

        return sendAuthor&&sendFans ? Result.success("操作成功",null)
                :Result.fail("操作成功,发送消息失败",null);
    }

    @Override
    public Result rejectReview(Integer songId, String reason) throws Exception {
        if (songId==null || reason==null|| reason.isEmpty()) {
            return Result.fail("songId或reason不为空",null);
        }
        boolean reject=songDao.rejectReview(songId,reason);
        if (!reject) {
            return Result.fail("操作失败", null);
        }
        // 操作成功，发送失败消息提示
        Song song = songDao.getSongById(songId);
        Integer receiverId = song.getUserId();
        News news = new News();
        news.setReceiverId(receiverId);
        news.setContent("您的歌曲 " + song.getName() + " 审核未通过，原因：" + reason);
        boolean send = newsDao.insert(news);
        return send ? Result.success("操作成功", null)
                : Result.fail("操作成功, 发送消息失败", null);
    }





    private List<SongDTO> convertAndEnrichSongs(List<Song> songEntityList) throws SQLException {
        List<SongDTO> dtos = new ArrayList<>();
        Set<Integer> userIds = songEntityList.stream()
                .map(Song::getUserId)
                .collect(Collectors.toSet());
        UserDaoImpl userDao = new UserDaoImpl();
        Map<Integer, User> userMap = userDao.getUsersByIds(userIds);
        // 转换并填充作者信息
        for (Song entity : songEntityList) {
            SongDTO dto = convertToDto(entity);
            User user = userMap.get(entity.getUserId());
            if (user != null) {
                dto.setUserName(user.getUserName());
            } else {
                dto.setUserName("未知");
                System.err.println("用户不存在: userId=" + entity.getUserId());
            }
            dtos.add(dto);
        }
        return dtos;
    }

    //entity -> dto
    public SongDTO convertToDto(Song entity) {
        SongDTO dto = new SongDTO();
        dto.setId(entity.getId());
        dto.setUserId(entity.getUserId());
        dto.setColumnId(entity.getColumnId());
        dto.setCheckId(entity.getCheckId());
        dto.setLikes(entity.getLikes());
        dto.setPlayCount(entity.getPlayCount());
        dto.setStatus(entity.getStatus());
        dto.setName(entity.getName());
        dto.setSongPath(entity.getSongPath());
        dto.setReason(entity.getReason());
        dto.setCreatedAt(entity.getCreatedAt());
        return dto;
    }

    //dto -> entity
    public Song convertToEntity(SongDTO dto) {
        Song entity = new Song();
        entity.setId(dto.getId());
        entity.setUserId(dto.getUserId());
        entity.setColumnId(dto.getColumnId());
        entity.setCheckId(dto.getCheckId());
        entity.setLikes(dto.getLikes());
        entity.setPlayCount(dto.getPlayCount());
        entity.setStatus(dto.getStatus());
        entity.setName(dto.getName());
        entity.setSongPath(dto.getSongPath());
        entity.setReason(dto.getReason());
        entity.setCreatedAt(dto.getCreatedAt());
        return entity;
    }

    //entityList -> dtoList
    private List<SongDTO> convertToDto(List<Song> entities) {
        List<SongDTO> dtos = new ArrayList<>();
        for (Song entity : entities) {
            dtos.add(convertToDto(entity));
        }
        return dtos;
    }
}
